package com.iknight.theory.controller;

import com.iknight.mgr.core.utils.IkgStringUtils;
import com.iknight.theory.api.TeRecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONObject;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ResourceLoader;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author JeryZym
 * @date 2017/12/20
 */
@RestController
@RequestMapping("/rest/excel")
@Api(value = "excel导出工具类控制器")
public class ExportExcelUtils {

    @Autowired
    private TeRecordService teRecordService;

    /**
     * param format :{
     * fileName:'',
     * sheets:[
     * {sheetname:'', filter:{}},
     * {sheetname:'', filter:{}}
     * ]
     * }
     *
     * @param param
     * @param request
     * @param response
     * @throws IOException
     */
    @GetMapping("/exportExcel")
    @ApiOperation(value = "导出")
    public void exportExcel(@RequestParam("param") String param, HttpServletRequest request, HttpServletResponse response) throws IOException {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        JSONObject jo = JSONObject.fromObject(URLDecoder.decode(param, "UTF-8"));

        String fileName = IkgStringUtils.ObjectToString(jo.get("fileName"));
        Object sheets = jo.get("sheets");

        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFCellStyle headerStyle = workbook.createCellStyle();//默认首行样式

//        headerStyle.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
        headerStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN);
        headerStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN);
        headerStyle.setBorderRight(XSSFCellStyle.BORDER_THIN);
        headerStyle.setBorderTop(XSSFCellStyle.BORDER_THIN);
        headerStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);

        XSSFFont font = workbook.createFont();
//        font.setColor(HSSFColor.BLACK.index);
        font.setFontHeightInPoints((short) 9);
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        font.setFontName("微软雅黑");
        headerStyle.setFont(font);
        headerStyle.setWrapText(false);//自动换行

        if ((null == sheets) || (null != sheets && ((List) sheets).size() == 0)) {//如果没有定义sheets信息，将生成错误表
            String errMsg = "未发现定义的sheet信息，系统自动导出空白页";
            workbook = createErrorWorkbook(workbook, headerStyle, errMsg);
        } else {
            //进行数据绘制
            List<Map> sheetLs = (List<Map>) sheets;
            int n = 0;

            for (Map sheet : sheetLs) {
                String sheetName = IkgStringUtils.ObjectToString(sheet.get("sheetname"));
                Map filter = (Map) sheet.get("filter");
                if (sheetName.equals("")) {
                    n++;
                    sheetName = "Sheet" + n;
                }
                workbook = createWorkSheet(workbook, headerStyle, sheetName, filter);
            }
        }

        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        try {
            workbook.write(os);
            byte[] content = os.toByteArray();
            InputStream is = new ByteArrayInputStream(content);
            // 设置response参数，可以打开下载页面
            response.reset();
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename="
                    + new String((fileName + ".xlsx")
                    .getBytes(), "iso-8859-1"));
            ServletOutputStream out = response.getOutputStream();

            bis = new BufferedInputStream(is);
            bos = new BufferedOutputStream(out);
            byte[] buff = new byte[4096];

            int bytesRead;

            while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                bos.write(buff, 0, bytesRead);
            }
        } catch (final IOException e) {
            e.printStackTrace();
        } finally {
            if (bis != null)
                bis.close();
            if (bos != null)
                bos.close();
        }
    }

    /**
     * 当查询数据出现异常或者生成异常时，自动生成错误表格
     *
     * @param workbook
     * @param headerStyle
     * @param errMsg
     * @return
     */
    private XSSFWorkbook createErrorWorkbook(XSSFWorkbook workbook, XSSFCellStyle headerStyle, String errMsg) {
        SimpleDateFormat sdf = new SimpleDateFormat("ss.SSSS");

        XSSFSheet sheet = workbook.createSheet("错误提示页" + sdf.format(Calendar.getInstance().getTime()));

        XSSFRow row = sheet.createRow(0);

        XSSFCell cell = row.createCell((short) 0);
        cell.setCellStyle(headerStyle);
        XSSFRichTextString text = new XSSFRichTextString("错误提示");
        cell.setCellValue(text.toString());

        XSSFRow msgRow = sheet.createRow((short) 1);
        cell = msgRow.createCell((short) 0);
        cell.setCellValue(errMsg);
        return workbook;
    }

    /**
     * 创建Sheet页
     *
     * @param workbook
     * @param headerStyle
     * @param sheetName
     * @param filter
     * @return
     */
    private XSSFWorkbook createWorkSheet(XSSFWorkbook workbook, XSSFCellStyle headerStyle, String sheetName, Map<String, Object> filter) {
        XSSFSheet xs = workbook.createSheet(sheetName);
        //参数遍历
//        String className = IkgStringUtils.ObjectToString(filter.get("className"));
        String methodName = IkgStringUtils.ObjectToString(filter.get("method"));
        Object param = filter.get("args");

        if (methodName.equals("")) {
            return createErrorWorkbook(workbook, headerStyle, "未明确定义查询的方法");
        }
        if (null == param) {
            return createErrorWorkbook(workbook, headerStyle, "未传递合法的参数");
        }

        List<Map> result = null;
        if (methodName.equals("getTranPowerByRecordId")) {
            result = teRecordService.getTranPowerByRecordId((Map) param);

        } else if (methodName.equals("getSegPowerByRecord")) {
            result = teRecordService.getSegPowerByMainRecordId((Map) param);
        }

        XSSFCellStyle style = workbook.createCellStyle();
        XSSFFont font = workbook.createFont();
        font.setFontHeightInPoints((short) 9);
        font.setFontName("微软雅黑");

        style.setFont(font);
        style.setWrapText(false);//自动换行

        List<String> keyls = new ArrayList<>();

        if (result instanceof List && result.size() > 0) {
            //识别fieldName
            Map<String, Object> header = result.get(0);
            XSSFRow row = xs.createRow((short) 0);
            int idx = 0;

            for (Map.Entry<String, Object> entry : header.entrySet()) {

                XSSFCell cell = row.createCell((short) idx);
                cell.setCellStyle(headerStyle);
                cell.setCellValue(entry.getKey());
                keyls.add(entry.getKey());
                idx++;
            }

            int i = 0;
            for (Map map : result) {
                XSSFRow tempRow = xs.createRow(i + 1);

                for (int k = 0; k < keyls.size(); k++) {
                    String key = keyls.get(k);
                    XSSFCell cell = tempRow.createCell((short) k);
                    cell.setCellValue(IkgStringUtils.ObjectToString(map.get(key)));
                    cell.setCellStyle(style);
                    xs.autoSizeColumn(k);
                }
                i++;
            }
        }

        return workbook;
    }

}
